﻿package model.poker;

/**
 * 桌
 * @author qykings
 *
 */
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import manager.ManagerPlayers;
import manager.Player;
import model.db.vo.TableNameVo;
import model.memCached.MemCachedManage;
import model.message.MessageVo;

import org.jboss.netty.channel.Channel;
import org.json.simple.JSONValue;

import protocol.poker.Poker_protocol;
import send.Sender;
import util.KIntChange;
import util.KJsonObject;
import util.KPrintInfo;
import config.SystemDefine;
import config.poker.PokerConfig;

public class Table {
	/**
	 * 台号
	 */
	private int								tableID;
	
	// 当前桌的玩家列表
	private ArrayList<Channel>				playerList		= new ArrayList<Channel>();
	// 已经准备的了玩家 (改进不用socket 用int)
	private ArrayList<Channel>				alreadyList		= new ArrayList<Channel>();
	
	// 扑克的数据
	private ArrayList<Poker>				pokerArrayList	= new ArrayList<Poker>();
	
	// /发给当前玩家
	private int								currentPlayer	= 0;
	
	/**
	 * 
	 * 抢地主数据 以id为key存倍数
	 */
	private HashMap<Integer, Integer>		robleadMap		= new HashMap<Integer, Integer>();
	// /是否已经结束抢地主
	private Boolean							isRobLead		= false;
	// 地主（在消息队列的id）
	private int								robleadId;
	
	private ArrayList<Poker>				lastSendPokerArr;
	
	private int								lastPlayerID;
	private ArrayList<Poker>				lastSend;
	// 玩家扑克数据 (队列中心的id)
	private Map<Integer, ArrayList<Poker>>	playerPokerMap	= new HashMap<Integer, ArrayList<Poker>>();
	
	public void start() {
		Shuffle();
		try {
			send_people_Enough();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void send_people_Enough() throws IOException {
		// /告诉客户端人数够了可以准备
		
		Poker_protocol poker_protocol = new Poker_protocol();
		poker_protocol.setOperate(PokerConfig.getInstance().getPoker_people_Enough());
		
		String string = "";//KJsonObject.encode(poker_protocol.getAllData());
		int length = playerList.size();
		for (int i = 0; i < length; i++) {
			
			Channel channel = playerList.get(i);
			channel.write(string);
		}
		
	}
	
	// 洗牌
	private void Shuffle() {
		ShufflePoker shufflePoker = new ShufflePoker();
		pokerArrayList = shufflePoker.getPokerArr();
	}
	
	/**
	 * 有没有这个人
	 * 
	 * @param id
	 * @return
	 */
	public Boolean haveThisPeople(Channel channel) {
		
		for (int i = 0; i < playerList.size(); i++) {
			if (playerList.get(i) == channel) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 已经准备的玩家
	 * 
	 * @param id
	 * @throws IOException
	 */
	public void readyPeople(Channel channel) throws IOException {
		for (int i = 0; i < playerList.size(); i++) {
			if (playerList.get(i) == channel) {
				if (!alreadyListHave(channel)) {
					alreadyList.add(playerList.get(i));
				}
			}
		}
		
		if (alreadyList.size() == 3) {
			// 可以开始了 ,发牌
			Poker_send_getData();
		}
	}
	
	private boolean alreadyListHave(Channel channel) {
		for (int i = 0; i < alreadyList.size(); i++) {
			if (alreadyList.get(i) == channel) {
				return true;
			}
		}
		return false;
	}
	
	private void Poker_send_getData() throws IOException {
		Poker poker = null;
		// 留3张做底牌给地主
		int lenght = pokerArrayList.size();
		
		for (int i = 0; i < lenght; i++) {
			if (i < 49) {
				Poker_send(pokerArrayList.get(i), false);
			} else {
				Poker_send(pokerArrayList.get(i), true);
			}
			
		}
		
		Poker_send_over();
	}
	
	private void Poker_send_over() throws IOException {
		
		Poker_protocol poker_protocol = new Poker_protocol();
		poker_protocol.setOperate(PokerConfig.getInstance().getPoker_send_Complete());
		String string ="";// KJsonObject.encode(poker_protocol.getAllData());
		
		int length = playerList.size();
		for (int i = 0; i < length; i++) {
			
			// Sender.GetInstance().onlySend(
			playerList.get(i).write(string);
		}
		
		// 抢地主
		RobLead_start();
	}
	
	/**
	 * 开始抢地主
	 */
	private void RobLead_start() throws IOException {
		
		Poker_protocol poker_protocol = new Poker_protocol();
		poker_protocol.setOperate(PokerConfig.getInstance().getPoker_RobLead_start());
		
		String string = "";//KJsonObject.encode(poker_protocol.getAllData());
		
		int length = playerList.size();
		for (int i = 0; i < length; i++) {
			playerList.get(i).write(string);
		}
		
	}
	
	/**
	 * 发底牌 isFloor 是不是底牌
	 * 
	 * @param p
	 */
	private void Poker_send(Poker p, Boolean isFloor) {
		try {
			// 队列中心的id
			Channel channel = playerList.get(currentPlayer);
			Player player=ManagerPlayers.getInstance().getPlayerByChan(channel);
			HashMap maps = (HashMap) MemCachedManage.getInstance().get(TableNameVo.T_user + player.id);
			
			Poker_protocol pr = new Poker_protocol();
			pr.getPokersList().add(p);
			pr.setIsFloor(isFloor);
			pr.setOperate(PokerConfig.getInstance().getPoker_send());
			pr.setUserId(KIntChange.intChange(maps.get("id")));
			String string = "";//KJsonObject.encode(pr.getAllData());
			
			ArrayList<Poker> pokersArr = (ArrayList<Poker>) playerPokerMap.get(currentPlayer);
			
			if (pokersArr == null) {
				playerPokerMap.put(currentPlayer, pr.getPokersList());
			} else {
				pokersArr.add(p);
			}
			
			try {
				if (isFloor) {
					tableBroadMsg(pr);
				} else {
					playerList.get(currentPlayer).write(string);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			KPrintInfo.println(currentPlayer + "-----before+");
			if (currentPlayer < playerList.size() - 1) {
				currentPlayer++;
			} else {
				currentPlayer = 0;
			}
			KPrintInfo.println(currentPlayer + "-----end+");
		} catch (Exception e) {
			KPrintInfo.println(e + "---Poker_send_getData--error");
		}
	}
	
	// 处理抢地主
	public void handleLeadTimes(MessageVo vo) throws IOException {
		// {"Time":3,"pokerArr":null,"Type":10005,"operate":7}
		
		if (robleadMap.size() < 3 && !isRobLead) {
			
			HashMap map = (HashMap) vo.getContent();
			int times = KIntChange.intChange(map.get("Time"));
			
			if (times < 3) {
				robleadMap.put(vo.getId(), times);
			} else {
				isRobLead = true;
				robleadId = vo.getId();
				sendLeadTime(3);
			}
			
			if (robleadMap.size() == 3) {
				// // 最大倍数
				int maxTimes = 0;
				//
				for (Map.Entry<Integer, Integer> myEntry : robleadMap.entrySet()) {
					Integer tempVo = myEntry.getValue();
					Integer ids = myEntry.getKey();
					Integer tempTimes = (Integer) tempVo;
					if (maxTimes == 0 || maxTimes < tempTimes) {
						maxTimes = tempTimes;
						robleadId = ids;
					}
				}
				//
				if (maxTimes > 0) {
					sendLeadTime(maxTimes);
				} else {
					// // 重新发牌
				}
			}
		}
		
	}
	
	private void sendLeadTime(int times) throws IOException {
		Poker_protocol poker_protocol = new Poker_protocol();
		poker_protocol.setOperate(PokerConfig.getInstance().getPoker_RobLead_enter());
		poker_protocol.setRobleadId(times);
		poker_protocol.setRobleadId(robleadId);
		tableBroadMsg(poker_protocol);
	}
	
	// 出牌
	public void sendCard(MessageVo msg) {
		lastPlayerID = msg.getId();
		lastSendPokerArr = (ArrayList<Poker>) msg.getContent();
		
		ArrayList<Poker> sourcePokers = (ArrayList<Poker>) playerPokerMap.get(lastPlayerID);
		
		if (clearPoker(lastSendPokerArr, sourcePokers)) {
			Poker_protocol poker_protocol = new Poker_protocol();
			poker_protocol.setOperate(PokerConfig.getInstance().getPoker_Play_Card_send());
			poker_protocol.setPokersList(lastSendPokerArr);
			poker_protocol.setUserId(msg.getId());
			
			String msgstr = JSONValue.toJSONString(poker_protocol);
			
			try {
				Sender.GetInstance().Broadcast(msgstr);
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			// 检察是否出完牌了
			if (sourcePokers.size() == 0) {
				// 说明他羸了
				Poker_protocol poker_protocol_win = new Poker_protocol();
				poker_protocol_win.setOperate(PokerConfig.getInstance().getPoker_Play_Card_send());
				poker_protocol_win.setPokersList(lastSendPokerArr);
				poker_protocol_win.setUserId(msg.getId());
				
				String msgstr_win = JSONValue.toJSONString(poker_protocol_win);
				
				try {
					Sender.GetInstance().Broadcast(msgstr_win);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		}
		
	}
	
	private Boolean clearPoker(ArrayList<Poker> _pokerslist, ArrayList<Poker> _sourceList) {
		for (int j = 0; j < _pokerslist.size(); j++) {
			Poker _p1 = _pokerslist.get(j);
			for (int i = 0; i < _sourceList.size(); i++) {
				Poker _p2 = _sourceList.get(i);
				if (comparePoker(_p1, _p2)) {
					_sourceList.remove(i);
					return true;
				}
			}
		}
		
		return false;
	}
	
	private Boolean comparePoker(Poker p1, Poker p2) {
		
		if (p1.getColor() != p2.getColor()) {
			return false;
		}
		
		if (p1.getValue() != p2.getValue()) {
			return false;
		}
		
		return true;
	}
	
	/**
	 * 
	 * @param arr1
	 * @param arr2
	 * @return
	 */
	private Boolean obServerPokerIsExit(ArrayList<Poker> arr1, ArrayList<Poker> arr2) {
		arr1.size();
		
		for (int i = 0; i < arr1.size(); i++) {
			
		}
		
		return false;
	}
	
	/**
	 * 广播这张台
	 */
	public void tableBroadMsg(Poker_protocol p) throws IOException {
		
		String msg ="";// KJsonObject.encode(p.getAllData());
		for (int i = 0; i < playerList.size(); i++) {
			// Sender.GetInstance().onlySend(playerList.get(i), msg);
			playerList.get(i).write(msg);
		}
		
	}
	
	public ArrayList<Channel> getPlayerList() {
		return playerList;
	}
	
	public void setPlayerList(ArrayList<Channel> playerList) {
		this.playerList = playerList;
	}
	
	public int getTableID() {
		return tableID;
	}
	
	public void setTableID(int tableID) {
		this.tableID = tableID;
	}
	
	public void destory() {
		tableID = 0;
		playerList = null;
		alreadyList = null;
		pokerArrayList = null;
		robleadMap = null;
		lastSendPokerArr = null;
		lastSend = null;
		playerPokerMap = null;
	}
	// /end class
}
